package core

import (
	"sync"
	"time"
)

// Cache 缓存接口
type Cache interface {
	// Set 设置缓存
	Set(key string, value interface{}, expiration time.Duration)
	// Get 获取缓存
	Get(key string) (interface{}, bool)
	// Delete 删除缓存
	Delete(key string)
	// Clear 清空缓存
	Clear()
}

// 缓存项
type cacheItem struct {
	value      interface{} // 缓存值
	expiration time.Time   // 过期时间
	created    time.Time   // 创建时间
}

// 是否过期
func (item *cacheItem) isExpired() bool {
	if item.expiration.IsZero() {
		return false
	}
	return time.Now().After(item.expiration)
}

// MemoryCache 内存缓存
type MemoryCache struct {
	items    map[string]cacheItem // 缓存项
	mu       sync.RWMutex         // 读写锁
	interval time.Duration        // 清理间隔
	stop     chan struct{}        // 停止信号
}

// NewMemoryCache 创建内存缓存
func NewMemoryCache(cleanupInterval time.Duration) *MemoryCache {
	c := &MemoryCache{
		items:    make(map[string]cacheItem),
		interval: cleanupInterval,
		stop:     make(chan struct{}),
	}

	// 启动定期清理
	go c.startCleanup()

	return c
}

// Set 设置缓存
func (c *MemoryCache) Set(key string, value interface{}, expiration time.Duration) {
	c.mu.Lock()
	defer c.mu.Unlock()

	var exp time.Time
	if expiration > 0 {
		exp = time.Now().Add(expiration)
	}

	c.items[key] = cacheItem{
		value:      value,
		expiration: exp,
		created:    time.Now(),
	}
}

// Get 获取缓存
func (c *MemoryCache) Get(key string) (interface{}, bool) {
	c.mu.RLock()
	defer c.mu.RUnlock()

	item, found := c.items[key]
	if !found {
		return nil, false
	}

	// 检查是否过期
	if item.isExpired() {
		return nil, false
	}

	return item.value, true
}

// Delete 删除缓存
func (c *MemoryCache) Delete(key string) {
	c.mu.Lock()
	defer c.mu.Unlock()

	delete(c.items, key)
}

// Clear 清空缓存
func (c *MemoryCache) Clear() {
	c.mu.Lock()
	defer c.mu.Unlock()

	c.items = make(map[string]cacheItem)
}

// 启动定期清理
func (c *MemoryCache) startCleanup() {
	ticker := time.NewTicker(c.interval)
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			c.deleteExpired()
		case <-c.stop:
			return
		}
	}
}

// 删除过期项
func (c *MemoryCache) deleteExpired() {
	c.mu.Lock()
	defer c.mu.Unlock()

	now := time.Now()
	for key, item := range c.items {
		if !item.expiration.IsZero() && now.After(item.expiration) {
			delete(c.items, key)
		}
	}
}

// StopCleanup 停止清理
func (c *MemoryCache) StopCleanup() {
	close(c.stop)
}

// 全局缓存实例
var (
	AppCache Cache
)

// 初始化缓存
func init() {
	// 创建全局缓存实例，每10分钟清理一次过期项
	AppCache = NewMemoryCache(10 * time.Minute)
}
